package com.lst.tools.wx.smallroutine.utils;

import com.lst.tools.wx.smallroutine.vo.SmallRoutineIdVo;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.*;


/**
 * @author: Frank
 * @date: 2019/09/24 13:51
 * @version: V1.0
 */
public class SmallRoutineUtils {
    /**
     * 算法
     */
    private static final String ALGORITHMSTR = "AES/CBC/PKCS7Padding";

    /**
     * 加密类型
     */
    private static final String SIGN_TYPE = "AES";

    private static final String FORMAT = "png";

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * 解密用户敏感数据获取用户信息
     *
     * @param sessionKey    数据进行加密签名的密钥
     * @param encryptedData 包括敏感数据在内的完整用户信息的加密数据
     * @param iv            加密算法的初始向量
     */
    public static String decrypt(String sessionKey, String encryptedData, String iv) {
        try {
            byte[] sessionKeyBytes = Base64.decodeBase64(sessionKey);
            byte[] encryptedDataBytes = Base64.decodeBase64(encryptedData);
            byte[] ivBytes = Base64.decodeBase64(iv);
            Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
            Key key = new SecretKeySpec(sessionKeyBytes, SIGN_TYPE);
            cipher.init(Cipher.DECRYPT_MODE, key, generateIV(ivBytes));
            byte[] result = cipher.doFinal(encryptedDataBytes);
            return new String(result);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 生成iv
     *
     * @param iv
     * @return
     * @throws Exception
     */
    public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
        AlgorithmParameters algorithmParameters = AlgorithmParameters.getInstance(SIGN_TYPE);
        algorithmParameters.init(new IvParameterSpec(iv));
        return algorithmParameters;
    }

    public static boolean checkIdNeed(SmallRoutineIdVo smallRoutineIdResp) {
        return smallRoutineIdResp != null
                && StringUtils.isNotBlank(smallRoutineIdResp.getOpenid())
                && StringUtils.isNotBlank(smallRoutineIdResp.getUnionid());
    }

    public static void createRqCode(InputStream inputStream, HttpServletResponse response) throws IOException {
        Image img = ImageIO.read(inputStream);
        BufferedImage image = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
        Graphics2D gs = image.createGraphics();
        gs.drawImage(img, 0, 0, null);
        gs.dispose();
        img.flush();
        writeToStream(image, FORMAT, response.getOutputStream());
    }

    public static void writeToStream(BufferedImage image, String format, OutputStream stream) throws IOException {
        if (!ImageIO.write(image, format, stream)) {
            throw new IOException("Could not write an image of format " + format);
        }
    }
}
